package edu.vtc.clacky;

import java.math.BigInteger;
import java.util.ArrayList;

public class ClackStack {
    private ArrayList<Rational> theStack;
    
    public ClackStack()
    {
        theStack = new ArrayList<Rational>();
    }
    
    
    public void push(Rational newValue)
    {
    	theStack.add(0, newValue);
    }
    
    
    public Rational pop()
    {
        return theStack.remove(0);
    }
    
    
    public int size()
    {
        return theStack.size();
    }
    
    
    public Rational get(int theStackLevel)
    {
        return theStack.get(theStackLevel);
    }
    /**
     * Extends the theStack to size n. If the theStack is already that size nothing is done, otherwise
     * an appropriate number of zeros are added to the theStack to increase its size to n item.
     * 
     * @param theStack The theStack to manipulate.
     * @param newSize The desired size of the theStack. Additional zeros are added if necessary.
     */
	 private void extend(int newSize)
	    {
	        if (newSize > theStack.size()) {
	            int count = newSize - theStack.size();
	            for (int i = 0; i < count; ++i) theStack.add(new Rational(0, 1));
	        }        
	    }
    
    
    /**
     * Duplicates the item at position 0 in 'theStack' so that it also appears in position 1. All
     * other items are moved up. For example if the theStack contains 10 11 12 13 14 a call to
     * dup(theStack) produces 10 10 11 12 13 14.
     * 
     * If the theStack is empty there is no effect.
     * 
     * @param theStack The theStack to manipulate.
     */
    public static void dup(ArrayList<Rational> theStack)
    {
            theStack.add(0, theStack.get(0));
     
    }
    
   
    
    
    /**
     * Copies the item at position 'n' to position 0 and moves all items up. For example if the
     * theStack contains 10 11 12 13 14 a call to pick(theStack, 3) produces 13 10 11 12 13 14.
     * 
     * If 'n' is off the end of the theStack, the theStack is first extended with a suitable number
     * of zeros.
     * 
     * @param theStack The theStack to manipulate.
     * @param n The position of the item to be picked.
     */
    public static void pick(ArrayList<Rational> theStack, Rational n)
    {
        extend(theStack, n.add(new Rational (1, 1)));
        String temp = n.toString();
        int nInt = Integer.parseInt(temp);
        theStack.add(0, theStack.get(nInt));
    }

    
    /**
     * The item at position 'distance' in 'theStack' is moved to position 0. All items originally
     * in the range [0, 'distance') are moved up one place. For example if the theStack contains
     * 10 11 12 13 14 a call to rollUp(theStack, 3) produces 13 10 11 12 14.
     * 
     * If position 'distance' is off the end of the theStack, zeros are first added as appropriate
     * to extend the theStack to position 'distance.'
     *   
     * @param theStack The theStack to manipulate.
     * @param distance The position of the item to be brought into theStack position 0.
     */
    public static void rollUp(ArrayList<Rational> theStack, Rational distance)
    {
    	extend(theStack, distance.add(new Rational (1, 1)));
    	String temp = distance.toString();
        int distanceInt = Integer.parseInt(temp);
        Rational item = theStack.get(distanceInt);
        theStack.remove(distanceInt);
        theStack.add(0, item);
    }
    
    
    /**
     * The item at position 0 in 'theStack' is moved to position 'distance.' All items originally
     * in the range (0, 'distance'] are moved down one place. For example if the theStack contains
     * 10 11 12 13 14 a call to rollDown(theStack, 3) produces 11 12 13 10 14.
     * 
     * If position 'distance' is off the end of the theStack, zeros are first added as appropriate
     * to extend the theStack to position 'distance.'
     * 
     * @param theStack The theStack to manipulate.
     * @param distance The position where the item at theStack position 0 will be placed.
     */
    public static void rollDown(ArrayList<Rational> theStack, Rational distance)
    {
    	String distanceString = distance.toString();
    	int distanceInt = Integer.parseInt(distanceString);
        extend(distanceInt);
        Rational item = theStack.get(0);
        theStack.remove(0);
        String temp = distance.toString();
        int distanceInt = Integer.parseInt(temp);
        theStack.add(distanceInt, item);
    }
    /**
     * The item at position 0 in 'theStack' is swapped with position 1.
     * 
     * @param theStack The theStack to manipulate.
     */
    
    public static void swap(ArrayList<Rational> theStack)
    {
    	Rational zero = theStack.get(0);
    	Rational one = theStack.get(1);
    	theStack.set(0, one);
    	theStack.set(1, zero);
    }
}
